// 假设从服务端获取到列车的实时信息
export const getTrainDataByLineId = (currentLine, stationData) => {
    return new Promise((resolve, reject) => {
        // 构造一个0---length-1的随机索引作为起始站点
        // let startIndex = Math.floor(Math.random() * (length-1))
        let startIndex = 0;
        const startStationInfo = stationData[startIndex];
        const endStationInfo = stationData[startIndex + 1];
        // 由于站点坐标和路径坐标可能不会完全匹配，这里只是模拟数据，给列车虚构一个坐标点
        const trainData = {
            startIndex,
            currentPassengers: Math.ceil(Math.random() * 1000), // 随机生成当前车厢人数
            startStation: startStationInfo, // 起始站点信息
            destination: endStationInfo, // 终点站点信息
            lineName: currentLine.name, // 列车名称
            currentSpeed: Math.ceil(Math.random() * 100), // 随机生成当前车速
            currentPosition: currentLine.paths[2], // 随机生成当前车辆位置
        };
        resolve(trainData);
    });
};
let trainEntity;
let popupController;
// let metroIndex
// 渲染轨道列车
import SimpleLabel from "./Bubble/htmlMarker";

let tickEvent = null;

export const renderTrain = async (
    viewer,
    currentLine,
    trainInfo,
    metroIndex,
    stationData
) => {
    // 获取出发站点，得到metroIndex
    const { startIndex, currentPosition, currentSpeed } = trainInfo;
    console.log("renderTrain", trainInfo);
    metroIndex.value = startIndex;
    const pathIndex = currentLine.paths.findIndex(
        (path) => path === currentPosition
    );
    const { property, startTime, endTime } = handlePosition(
        currentLine,
        currentSpeed,
        pathIndex
    );
    trainEntity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([
            new Cesium.TimeInterval({
                start: startTime,
                stop: endTime,
            }),
        ]),
        position: property, // 车辆位置
        orientation: new Cesium.VelocityOrientationProperty(property),
        model: {
            scale: 0.5,
            uri: new URL("/src/assets/model/metro.gltf", import.meta.url).href,
            minimumPixelSize: 40, // 最小像素大小
        },
    });

    viewer.trackedEntity = trainEntity; // 跟踪实体
    viewer.clock.startTime = startTime.clone();
    viewer.clock.stopTime = endTime.clone();
    viewer.clock.currentTime = startTime.clone();
    // 监听时钟，如果列车到达站点，更新列车人数信息，并给一个暂停时间
    // 将一个函数正确地传递给 addEventListener，而不是执行其结果！！
    tickEvent = () => tickEventHandler(viewer, stationData, metroIndex);
    viewer.clock.onTick.addEventListener(tickEvent);
    // 显示气泡框
    popupController = new SimpleLabel(viewer, {
        attr: {
            lineName: trainInfo.lineName,
            currentPassengers: trainInfo.currentPassengers,
        },
        type: "carPopup",
        offset: [0, 300], //param1是x轴偏移量，param2是y轴偏移量
    });
    await popupController.addLabel();
};

// 移除列车
export const removeTrain = (viewer) => {
    viewer.entities.remove(trainEntity);
    // trainEntity = null
    popupController && popupController.removeMarker();
    //移除事件
    tickEvent && viewer.clock.onTick.removeEventListener(tickEvent);
    tickEvent = null;
};

let startTime;
// 处理漫游效果，使用TimeIntervalCollection
export const handlePosition = (currentLine, speed, pathIndex) => {
    const property = new Cesium.SampledProperty(Cesium.Cartesian3);
    // 这里的时间可以自己定义
    startTime = Cesium.JulianDate.fromDate(new Date(2015, 1, 1, 8));
    //通过速度计算最终时间
    const restPath = currentLine.paths.slice(
        pathIndex,
        currentLine.paths.length - 1
    );
    const positions = getPositions(restPath);
    //根据速度计算总时间和每段时间
    const { siteTimes, timeSum } = getSiteTimes(positions, speed);
    const endTime = Cesium.JulianDate.addSeconds(
        startTime,
        timeSum,
        new Cesium.JulianDate()
    );
    positions.forEach((position, index) => {
        const time = Cesium.JulianDate.addSeconds(
            startTime,
            siteTimes[index],
            new Cesium.JulianDate()
        );
        property.addSample(time, position); //将一个时间点和对应的位置添加到 property 对象中
    });
    return {
        property,
        startTime,
        endTime,
    };
};

// 将经纬度转为笛卡尔3
function getPositions(positions) {
    let cartesian3Arr = [];
    for (let i = 0; i < positions.length; i++) {
        let cartesian3 = Cesium.Cartesian3.fromDegrees(
            positions[i].lng,
            positions[i].lat,
            positions[i].alt
        );
        cartesian3Arr.push(cartesian3);
    }
    return cartesian3Arr;
}

//计算每个点位时间与总时间
// pArr:[{x,y,z}]
// speed number
const getSiteTimes = (pArr, speed) => {
    let timeSum = 0,
        times = [];
    for (var i = 0; i < pArr.length; i++) {
        if (i == 0) {
            times.push(0); //第0个时间为0
            continue;
        }

        // 计算总时间
        timeSum += spaceDistance([pArr[i - 1], pArr[i]]) / speed;
        // 将每段距离所用的时间收集起来
        times.push(timeSum);
    }
    return {
        timeSum: timeSum,
        siteTimes: times,
    };
};

//计算距离
export const spaceDistance = (positions) => {
    let distance = 0;
    for (let i = 0; i < positions.length - 1; i++) {
        let s = Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
        distance = distance + s;
    }
    return distance.toFixed(2);
};

export const removeCurrentRoute = (viewer) => {
    viewer.entities.remove(trainEntity);
};

const tickEventHandler = (viewer, stationData, metroIndex) => {
    const startPosition = trainEntity.position.getValue(
        viewer.clock.currentTime
    );
    //通过当前的metroIndex和速度计算下一个站点的坐标
    const { position } = stationData[metroIndex.value + 1];
    const endPosition = new Cesium.Cartesian3.fromDegrees(
        position.lng,
        position.lat
    );
    let distance = Cesium.Cartesian3.distance(startPosition, endPosition);
    // console.log(distance)
    // 当距离小于20米的时候，就可以给列车一个暂停
    if (distance <= 20) {
        // 站点id变大，下一次计算的distance也会变大
        metroIndex.value++;
        // 将列车暂停
        viewer.clock.shouldAnimate = false;
        // 2s后恢复
        setTimeout(() => {
            viewer.clock.shouldAnimate = true;
        }, 2000);
    }
    // 还需要通过startPosition计算气泡框坐标
    popupController && popupController.changePosition(startPosition);
};
